﻿using Newtonsoft.Json;
using NLog;
using OrBitDataModule.Interface;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.Xml;
using OrBitDataModule.FileHelper;
using OrBitDataModule.Common;
using System.IO.Ports;
using OrBitDataModule.Adaptor;
using HttpLib;

namespace OrBitDataModule.Base
{
    public class Context : IContext
    {
        public DataTaskBase DataTask { get; }
        public Context(DataTaskBase dataTask)
        {
            DataTask = dataTask;
        }

        /// <summary>
        /// 默认编码
        /// </summary>
        public Encoding DefaultEncoding => DataTask.DefaultEncoding;

        /// <summary>
        /// 任务唯一码
        /// </summary>
        public string UniqueId => DataTask.UniqueId;

        /// <summary>
        /// 任务名称
        /// </summary>
        public string TaskName => DataTask.TaskName;

        /// <summary>
        /// Webapi基础地址
        /// </summary>
        public string BaseApiUri => DataTask.BaseApiUri;

        /// <summary>
        /// 接口用户名
        /// </summary>
        public string UserName => DataTask.UserName;

        /// <summary>
        /// 接口名称
        /// </summary>
        public string ApiName => DataTask.ApiName;

        /// <summary>
        /// 登录接口token
        /// </summary>
        public string Token => DataTask.ApiName;
        /// <summary>
        /// 接口有效期
        /// </summary>
        public int Expiration => DataTask.Expiration;
        /// <summary>
        /// 设置参数
        /// </summary>
        public SettingDictionary SettingProperty => DataTask.SettingProperty;
        /// <summary>
        /// 定时调度器
        /// </summary>
        public QuartzScheduler Scheduler { get; } = new QuartzScheduler();
        /// <summary>
        /// 串口对象
        /// </summary>
        public SerialPort SerialPortInstance => DataTask.SerialPortInstance;
        /// <summary>
        /// Socket Client对象
        /// </summary>
        public SocketTcpClient TcpClientInstance => DataTask.TcpClientInstance;

        /// <summary>
        /// http请求对象
        /// </summary>
        public Http Http => Http.Instance;

        /// <summary>
        ///  
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="formMulti"></param>
        /// <returns></returns>
        public async Task<string> WebApiHttpPost(string apiName, string token, object formMulti)
        {
            var result = await WebApi.HttpPostAsync(apiName, token, formMulti);
            return result.Response;
        }

        /// <summary>
        /// 获取api token
        /// </summary>
        /// <param name="apiName"></param>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public async Task<(bool Result, string Token, int Expiration, string Message)> GetWebApiToken(string apiName, string userName, string password) => await WebApi.GetAccessTokenAsync(apiName, userName, password);

        /// <summary>
        /// /序列化json
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public string SerializeToJson<T>(T obj) => JsonConvert.SerializeObject(obj);

        /// <summary>
        /// 反序列化json
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public T DeserializeObject<T>(string json) => JsonConvert.DeserializeObject<T>(json);

        /// <summary> 
        /// 实体对象序列化成xml字符串 
        /// </summary> 
        /// <typeparam name="T"></typeparam> 
        /// <param name="obj"></param> 
        /// <returns></returns> 
        public string SerializeToXML<T>(T obj, Encoding encoding = null)
        {
            try
            {
                if (encoding == null)
                {
                    encoding = Encoding.Default;
                }
                var ser = new XmlSerializer(obj.GetType());
                using (var ms = new MemoryStream())
                {
                    using (var writer = new XmlTextWriter(ms, encoding))
                    {
                        writer.Formatting = System.Xml.Formatting.Indented;
                        ser.Serialize(writer, obj);
                    }
                    var xml = encoding.GetString(ms.ToArray());
                    xml = xml.Replace("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"", "");
                    xml = xml.Replace("xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"", "");
                    xml = Regex.Replace(xml, @"\s{2}", "");
                    xml = Regex.Replace(xml, @"\s{1}/>", "/>");
                    return xml;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public void WriteLog(string message) => this.WriteLog(message, LogLevel.Info);

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="logLevel"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public void WriteLog(string message, LogLevel logLevel) => this.WriteLog(this.TaskName, message, logLevel);

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="taskName"></param>
        /// <param name="message"></param>
        /// <param name="logLevel"></param>
        /// <returns></returns>
        public void WriteLog(string taskName, string message, LogLevel logLevel) => this.DataTask.WriteLog(taskName, message, logLevel, 0, "");
    }
}
